/*
 * File:    If.java
 * Created: 20-Feb-2009
 * Version: $Id$
 *
 * COPYRIGHT (C) 2009, Bitgate Mobile, LLC.  All Rights Reserved.
 *
 * software@bitgatemobile.com
 */

package com.webplasm.render.tags.u;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.webplasm.context.RenderContext;
import com.webplasm.render.engine.RenderException;
import com.webplasm.render.tags.TagInterface;
import com.webplasm.render.tags.WrappedNode;

/**
 * Provides functionality to perform determinative program flow.  This is the same as the &quot;if&quot; statement
 * provides by Java.
 * 
 * @author kenji
 * @since Webplasm 1.0
 */
public class If extends WrappedNode implements TagInterface {
	private static final String DESCRIPTION = "Provides an if/then/else/and/or mechanism to handle program flow.";

	public String getNamespace() {
		return "u";
	}
	
	public List<String> getAttributes() {
		return Arrays.asList("arg1", "arg2", "expr");
	}
	
	public List<String> getManagedNodes() {
		return Arrays.asList("then", "else");
	}

	public String getDescription() {
		return DESCRIPTION;
	}

	@Override
	public StringBuffer render(RenderContext rContext) throws RenderException {
		Map<String, WrappedNode> wrappedNodes = prepareNodes(thisNode);

		if (elements.get("arg1") == null) {
			throw new RenderException("u:if requires a test expression in arg1.");
		}
		
		if (elements.get("arg2") == null) {
			throw new RenderException("u:if requires a test expression in arg2.");
		}
		
		if (elements.get("expr") == null) {
			throw new RenderException("u:if requires an expression.");
		}
		
		if (wrappedNodes.get("then") == null) {
			throw new RenderException("u:if requires a &lt;then&gt; sub-element.");
		}
		
		String expression = elements.get("expr");
		WrappedNode thenNode = wrappedNodes.get("then");
		WrappedNode elseNode = wrappedNodes.get("else");
		
		if (expression.equals("eq") || expression.equals("==")) {
			if (getWrappedAttribute(rContext, "arg1").equals(getWrappedAttribute(rContext, "arg2"))) {
				return thenNode.render(rContext);
			}
			
			if (elseNode != null) {
				return elseNode.render(rContext);
			}
		} else if (expression.equals("lt") || expression.equals("lte")) {
			if (expression.equals("lte") && getWrappedAttribute(rContext, "arg1").equals(getWrappedAttribute(rContext, "arg2"))) {
				return thenNode.render(rContext);
			}
			
			if (getWrappedAttribute(rContext, "arg1").indexOf('.') != -1 && getWrappedAttribute(rContext, "arg2").indexOf('.') != -1) {
				float expr1 = Float.parseFloat(getWrappedAttribute(rContext, "arg1"));
				float expr2 = Float.parseFloat(getWrappedAttribute(rContext, "arg2"));
				
				if (expr1 < expr2) {
					return thenNode.render(rContext);
				}
			} else {
				int expr1 = Integer.parseInt(getWrappedAttribute(rContext, "arg1"));
				int expr2 = Integer.parseInt(getWrappedAttribute(rContext, "arg2"));
				
				if (expr1 < expr2) {
					return thenNode.render(rContext);
				}
			}
			
			if (elseNode != null) {
				return elseNode.render(rContext);
			}
		} else if (expression.equals("gt") || expression.equals("gte")) {
			if (expression.equals("gte") && getWrappedAttribute(rContext, "arg1").equals(getWrappedAttribute(rContext, "arg2"))) {
				return thenNode.render(rContext);
			}

			if (getWrappedAttribute(rContext, "arg1").indexOf('.') != -1 && getWrappedAttribute(rContext, "arg2").indexOf('.') != -1) {
				float expr1 = Float.parseFloat(getWrappedAttribute(rContext, "arg1"));
				float expr2 = Float.parseFloat(getWrappedAttribute(rContext, "arg2"));
				
				if (expr1 > expr2) {
					return thenNode.render(rContext);
				}
			} else {
				int expr1 = Integer.parseInt(getWrappedAttribute(rContext, "arg1"));
				int expr2 = Integer.parseInt(getWrappedAttribute(rContext, "arg2"));
				
				if (expr1 > expr2) {
					return thenNode.render(rContext);
				}
			}
			
			if (elseNode != null) {
				return elseNode.render(rContext);
			}
		}
		
		return new StringBuffer();
	}
}